impl Solution {
    pub fn valid_ip_address(query_ip: String) -> String {
        use std::str::FromStr;
        fn is_ipv4(arr: Vec<&str>) -> bool {
            if arr.len() != 4 { return false; }
            for ip in arr {
                if ip.len() < 1 || ip.len() > 3 { return false; }
                let ip_num = ip.parse::<i32>();
                if ip_num.is_err() || ip_num.as_ref().unwrap() > &255 || ip_num.as_ref().unwrap().to_string().len() != ip.len() { return false; }
            }
            true
        }
        fn is_ipv6(arr: Vec<&str>) -> bool {
            if arr.len() != 8 { return false; }
            for ip in arr {
                if ip.len() < 1 || ip.len() > 4 { return false; }
                for ch in ip.chars() {
                    if !char::is_ascii_digit(&ch) && !(ch >= 'a' && ch <= 'f' || ch >= 'A' && ch <= 'F') { return false; }
                }
            }
            true
        }

        if query_ip.contains(".") {
            return if !is_ipv4(query_ip.split(".").collect::<Vec<_>>()) { "Neither".to_string() } else { "IPv4".to_string() };
        }
        return if !is_ipv6(query_ip.split(":").collect::<Vec<_>>()) { "Neither".to_string() } else { "IPv6".to_string() };
    }
}


// 方法2：函数式+std::net|ipaddress+微调IPv6
impl Solution2 {
    pub fn valid_ip_address(query_ip: String) -> String {
        use std::net::{Ipv4Addr, Ipv6Addr};
        query_ip
            .parse::<Ipv4Addr>()
            .map(|_| String::from("IPv4"))
            .or(query_ip
                .split(":")
                .map(|x| if x.is_empty() { "g" } else { x })
                .collect::<Vec<_>>()
                .join(":")
                .parse::<Ipv6Addr>()
                .map(|_| String::from("IPv6")))
            .unwrap_or_else(|_| String::from("Neither"))
    }
}


// 调用 impl Solution?